//狼人杀1.0
victim = []
players = []
roles = []
alive = []
vote = {}

announcement = "/me尚未开始游戏"
announce = (msg) => {
  announcement = msg
  drrr.print(msg)
}


roleName = []
rolesMap = {
  3 : [0, 1, 1],	
  4 : [0, 1, 1, 1],
  5 : [0, 1, 1, 1, 1],
  6 : [0, 0, 1, 1, 1, 1],
  7 : [0, 0, 1, 1, 1, 1, 1],
  8 : [0, 0, 1, 1, 1, 1, 1, 1]
}

select = (cont, users) => {
  result = users.filter((u) => cont.includes(u))
  if result.length
  then result.reduce((a, b)=> if a.length > b.length then a else b)
  else ""
}

most = (arr) => {
  counts = arr.reduce((a, c) => {
    a[c] = (if a.hasOwnProperty(c) then a[c] else 0) + 1
    a
  }, Object())
  print(counts)
  maxCount = Math.max.apply(Object(), Object.values(counts))
  print(maxCount)
  Object.keys(counts).filter(k => counts[k] === maxCount)
}

passJudge = () => {
  undercover = alive.filter((live, index) => live && roles[index] == 0)
  people = alive.filter((live, index)=> live && roles[index] != 0)
  if undercover.length && people.length && (undercover.length+people.length !=2) then -1
  else if undercover.length then 0
  else 1
}

state prepare {
	
  victim = []
  players = []
  roles = []
  alive = []
  vote = {}
  roleName = []
  
  event [msg, me] (user, cont: "^/config") => {
    config = cont.replace("/config", "").trim()
    valid_roles = "valid roles:\n" +
          Object.keys(roleName).map(k => String(k) + ": " + roleName[k]).join("\n")
    if config then {
      rs = JSON.parse(config)
      invalid = rs.filter(r => !(r in roleName))
      if !rs || !Array.isArray(rs) then
        drrr.print("invalid argument: " + config)
      else if invalid.length then
        drrr.print("invalid roles: " + String(invalid)
          + "\n" + valid_roles)
      else {
        roles = rs
        drrr.print(roles.map((r) => roleName[r]).join("\n") + "\nok, config done")
      }
    }
    else {
      roles = []
      drrr.print(valid_roles + "\nok, random config")
    }
  }
  event [msg, me] (user, cont: "^\\+1$") => {
    if players.includes(user) then
      drrr.print("/me" + user + " 已经加入了")
    else{
      players.push(user)
      drrr.print("/me" + user + " 加入游戏")
    }
  }
  event [msg, me] (user, cont: "^-1$") => {
    if players.includes(user) then {
      players.splice(players.indexOf(user), 1);
      drrr.print("/me" + user + " 退出游戏")
    }
    else drrr.print("/me" + user + " 不在游戏中")
  }
  event [msg, me] (user, cont: "^/who$") => {
    if players.length then {
    	drrr.print("玩家：\n" + players.map((user, index) => String(index + 1) + ". " + user).join("\n"))
    } else drrr.print("/me 没有玩家")
  }
  event [msg, me] (user, cont: "^/go$") => {
    if players.length in rolesMap then {
		
	going prelude
	}
    else drrr.print("/me需满足 3 - 8 人, 目前 " + String(players.length) + "人")
  }
  announce("/me [+1] 加入, [-1] 退出, [/w] 玩家, [/go] 开始")
}

state prelude {
  drrr.print("玩家：\n" + players.map((user, index) => String(index + 1) + ". " + user).join("\n"))

  roles = rolesMap[players.length]
  roles.sort(()=>Math.random() - 0.5)
  alive = roles.map((x) => true)

  players.forEach((user, index) => {
     later index * 3500 drrr.dm(user, "你的卡牌是:" + roleName[roles[index]])
    
  })

  later players.length * 4000 going day_discussion
}


state day_discussion {
  index = 0
  while (index < players.length) && (alive[index] == 0) index++;
  announce("/me请 @" + players[index] + " 开始发言 ([over] 结尾,[/skip] 跳过此人)")
  event [msg, me] (user, cont) => {
    if players[index] == user then {
      if cont.includes("over") || cont.startsWith("/skip") then {
        index++ 
        while (index < players.length) && (alive[index] == 0) index++;
        if index >= players.length
        then later 3500 going day_vote
        else announce("/me请 @" + players[index] + " 开始发言 ([over] 结尾)")
      }
    }
  }
}

state day_vote {
  announce("/me请开始投票 ([/vote] 看目前已投票玩家, *私信* [人名] 或是 [no] 弃票)")
  vote = {}

  cur_alive = players.filter((u, i) => alive[i]).join("\n")
  alive.forEach((live, index) => {
    if live then
      later (2000 * index) drrr.print( "请开始投票，选项有：\n" + cur_alive)
  })

  event [msg,dm] (user, cont) => {
    if players.includes(user) then {
		if cont.startsWith("/execute")
        then {
          
          later 3500 going day_execute
        }
      if alive[players.indexOf(user)] then {
        if vote.hasOwnProperty(user) then
            drrr.dm(user, "一人一票，落票无悔")
        else {
          the = select(cont, players)
          if the then {
            if alive[players.indexOf(the)] then {
              vote[user] = the
              drrr.dm(user, "ok, 你投了 " + the)
              if Object.keys(vote).length == players.filter((name, index)=>alive[index]).length
              then later 3500 going day_execute
            }
            else drrr.dm(user, the + " ta已经出局了")
          }
          else if cont.startsWith("no") then {
            vote[user] = "no"
            drrr.dm(user, "ok, 你弃票了")
            if Object.keys(vote).length == players.filter((name, index)=>alive[index]).length
            then later 3500 going day_execute
          } else drrr.dm(user, "没这个人")
        }
      } else drrr.dm(user, "你没有权利投票")
    } 
  }
  event [msg, me] (user, cont: "^/vote$") => {
    drrr.print("/me目前已投票：" + Object.keys(vote).join(", "))
  }
}

state day_execute {
  louis = most(Object.values(vote).filter((x) => x != "no"))
  announce("/me 最高得票人：" + louis.map((x) => "@" + x).join(", "))

  for name of louis
    alive[players.indexOf(name)] = false

  later 3500 {
    drrr.print("/me 目前的玩家：" + players.filter((u, i) => alive[i]).join(", "))
    if passJudge() < 0
    then
      later 3500 going day_discussion
    else
      later 3500 going game_over
  }
}

state game_over {
  cur_role = players.map((name, idx) => name + "：" + roleName[roles[idx]]).join("\n")
  if passJudge()
  then
    drrr.print("/me游戏结束, 好人胜出")
  else
    drrr.print("/me游戏结束, 卧底胜出")
  later 2000 drrr.print(cur_role)
}

werewolf = () => {
  event [msg, me, dm] (user, cont: "^/r$") => {
    if players.includes(user) then {
      index = players.indexOf(user)
      if roles[index] then drrr.dm(user, "你的卡牌是:" + roleName[roles[index]])
      else drrr.dm(user, "你的卡牌是：" + players.filter((user, index)=>roles[index] == 0).join(", "))
    }
    else drrr.dm(user, "你不是玩家")
  }

  event [msg, me, dm] (user, cont: "^/a$") => {
    if alive.length
    then drrr.print("玩家：\n" + players.map((user, index) => String(index + 1) + ". " + user + (if alive[index] then " 活" else " 死")).join("\n"))
    else drrr.print("/me没有玩家，请开始游戏")
  }

  event [msg, me, dm] (user, cont: "^/s$") => {
    drrr.print(announcement)
  }

  event [msg, me, dm] (user, cont: "^/help$") => {
    drrr.print("/help 本手册\n/s 现在游戏状态\n/w 当前所有玩家\n/r 自己的卡牌\n/game 开始报名（如有游戏则重新）")
  }
 event [msg, me] (user, cont: "^/game$") => going prepare
 going prepare
}
werewolf();